package com.wxlgroup.springboot.controller;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wxlgroup.springboot.dao.FileDao;
import com.wxlgroup.springboot.entity.Files;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import com.wxlgroup.springboot.commons.Response;

/**
 * @auther:wxl
 * @Date:2022/5/24-05-24-22:11
 * @Description:com.wxlgroup.springboot.controller
 * @Version:1.0
 */
@RestController
@RequestMapping("/file")
public class FileController {


    @Value("${file.upload.path}")           //将配置文件的路径读取出来注入fileLoadPath中
    private String fileLoadPath;

    @Resource
    private FileDao fileDao;

    @PostMapping("/upload")
    public String uploadFile(MultipartFile file) throws IOException {
        //获取文件的全名称
        String originalFilename = file.getOriginalFilename();
        //获取文件的后缀名
        String type = FileUtil.extName(originalFilename);
        //获取文件的大小
        long size = file.getSize();
        //定义一个文件唯一的标识符
        String unique = IdUtil.fastUUID();
        String fileUUid=unique+ StrUtil.DOT+type;
        //创建文件目录
        File uploadFile = new File(fileLoadPath+fileUUid);
        //判断目标文件目录是否存在
        File parentFile = uploadFile.getParentFile();
        if(!parentFile.exists()){
            //如果父目录没有也会被创建
            parentFile.mkdirs();
        }
        //获取文件的md5
        String md5 = SecureUtil.md5(file.getInputStream());
        Files filesByMd5 = getFilesByMd5(md5);
        String url;
        if(filesByMd5==null){       //如果数据库有相同的md5说明文件已经下载过一次，不必在下载，节省磁盘空间
            //将文件写入磁盘
            file.transferTo(uploadFile);
            //设置文件的url
            url="http://localhost:8086/file/"+fileUUid;
        }else {
            url=filesByMd5.getUrl();
        }
        //将文件写入数据库
        Files saveFile = new Files();
        saveFile.setName(originalFilename);
        saveFile.setType(type);
        saveFile.setSize(size/1024);        //大小是KB
        saveFile.setUrl(url);
        saveFile.setMd5(md5);
        fileDao.insert(saveFile);
        return url;
    }


    /**
     *
     * @param fileUUid
     * @throws IOException
     */
    @GetMapping("/{fileUUid}")
    public void downLoad(@PathVariable String fileUUid, HttpServletResponse response) throws IOException {
        File downLoadFile = new File(fileLoadPath+fileUUid);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUid, "UTF-8"));
        response.setContentType("application/octet-stream");
        //通过文件字节流的方式写出文件
        os.write(FileUtil.readBytes(downLoadFile));
        //关闭流
        os.flush();
        os.close();
    }


    /**
     * 根据文件的md5查询数据库中是否有相同的md5
     * @param md5
     * @return 文件
     */
    public Files getFilesByMd5(String md5){
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        //根据传入的md5查询数据库有没有相同的已经存入的文件
        queryWrapper.eq("md5", md5);
        List<Files> files = fileDao.selectList(queryWrapper);
        //当查询到多个相同的md5记录时，只取第一个
        return files.size()==0? null :files.get(0);
    }


    /**
     * 文件管理的分页查询接口
     * @param pageNumber
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public Response findUserCounts(
            Integer pageNumber,
            Integer pageSize,
            String name){
        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_delete",false);
        queryWrapper.orderByDesc("id");
        if(!"".equals(name)){
            queryWrapper.like("name",name);
        }
        return new Response("200",fileDao.selectPage(new Page<>(pageNumber,pageSize),queryWrapper),"分页查询成功");

    }

    /**
     * 根据文件id删除单个文件
     * @param id
     * @return
     */
    @DeleteMapping("/delete/{id}")
    public Response deleteFileByid(@PathVariable Integer id){
        Files files = fileDao.selectById(id);
        files.setIsDelete(true);
        return new Response("200",fileDao.updateById(files),"修改成功");
    }

    /**
     * 根据文件批量删除文件
     * @param ids
     * @return
     */
    @PostMapping("/deletes")
    public Response deleteFilesById(@RequestBody List<Integer> ids){
        for (Integer id : ids) {
            Files file = fileDao.selectById(id);
            file.setIsDelete(true);
            fileDao.updateById(file);
        }
        return new Response("200",null,"批量删除成功");
    }


    @PostMapping("/update")
    public Response updateEnable(@RequestBody Files file){
        return new Response("200",fileDao.updateById(file),"修改状态成功");
    }
}
